
function BaseInteraction(coordinateConversionCallback)
{
  BaseLayers.call(this,coordinateConversionCallback);
  BaseGizmos.call(this);
  
  this.clickLayer = null;
  this.offset = null;
  this.processHooks = false;
  
  this.hooks = Array();
  this.hooks['MouseClick'] = Array();
  this.hooks['MouseMove'] = Array();
  this.hooks['KeyboardKeydown'] = Array();
  
}

BaseInteraction.inherit(BaseLayers);
BaseInteraction.inherit(BaseGizmos);

BaseInteraction.prototype.addClickLayer = function (name)
{
  this.clickLayer = new CanvasLayer(name,this.coordinateConversionCallback);
}

BaseInteraction.prototype.hasClickLayer = function ()
{
  return this.clickLayer != null;
}

BaseInteraction.prototype.addHook = function (type,callback)
{
  this.hooks[type].push(callback);
}

BaseInteraction.prototype.calculateOffset = function (object)
{
  var offsetVector = $V(object.offsetLeft,object.offsetTop); 
  if(object.offsetParent == null)
    return offsetVector;
  else
    return this.calculateOffset(object.offsetParent).add(offsetVector);
}

BaseInteraction.prototype.setupInteraction = function ()
{
  window.addEventListener('keydown',bind(this,this.keyboardKeydownCallback),true);
  this.offset = this.calculateOffset(this.getTopLayer().element);
  this.getTopLayer().element.addEventListener('mousemove',bind(this,this.mouseMoveCallback),true);
  this.getTopLayer().element.addEventListener('click',bind(this,this.mouseClickCallback),true);
}

BaseInteraction.prototype.startInteraction = function ()
{
  this.processHooks = true;
}

BaseInteraction.prototype.stopInteraction = function ()
{
  this.processHooks = false;
}

BaseInteraction.prototype.callHooks = function (name,arg)
{
  var summary = true;
  for(var i in this.hooks[name])
    summary &= this.hooks[name][i](arg);
    
  return summary;
}

BaseInteraction.prototype.keyboardKeydownCallback = function(e)
{
  if(!this.processHooks)
    return; 
  
  if(!this.callHooks('KeyboardKeydown',e))
  {
    e.preventDefault();
    return false;
  }
  
  return true;
}

BaseInteraction.prototype.mouseMoveCallback = function(e)
{
  if(!this.processHooks)
    return;
  
  var point = this.getTopLayer().convertCoord($V(e.pageX - this.offset.x, e.pageY - this.offset.y));
  
  if(this.hasClickLayer())
  {
    var pixel = this.clickLayer.getPixel(point);  
    for(var i in this.gizmos)
      this.gizmos[i].processMouseMove(point,pixel);
  }
    
  this.callHooks('MouseMove',point);
  
  return true;
}

BaseInteraction.prototype.mouseClickCallback = function(e)
{
  if(!this.processHooks)
    return;
  
  var point = this.getTopLayer().convertCoord($V(e.pageX - this.offset.x, e.pageY - this.offset.y));
  
  if(this.hasClickLayer())
  {
    var pixel = this.clickLayer.getPixel(point);  
    for(var i in this.gizmos)
      this.gizmos[i].processMouseClick(point,pixel);
  }  
  
  this.callHooks('MouseClick',point);
  
  return true;
}

